package com.tjetc.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tjetc.common.JsonResult;
import com.tjetc.dao.*;
import com.tjetc.entity.Admin;
import com.tjetc.entity.Merchant;
import com.tjetc.entity.User;
import com.tjetc.entity.view.MerchantOrderDay;
import com.tjetc.model.DateMoneyList;
import com.tjetc.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private MerchantMapper merchantMapper;

    /**
     * 登录接口，传入前端登录输入的用户名密码，返回JsonResult
     * */
    public JsonResult<Admin> login(Admin admin) {
        List<Admin> res_admin = adminMapper.selectByAdmin(admin);
        if(res_admin.size() > 1) {
           throw new RuntimeException("查询出重复的Admin");
        } else if(res_admin.size() == 0) {
            return new JsonResult<>(1, "用户名密码错误", null);
        }
        return new JsonResult<>(0, "", res_admin.get(0));
    }

    /**
     * 列出所有的admin用户
     * @return 返回列表
     */
    @Override
    public List<Admin> listAll() {
        return adminMapper.selectAll();
    }

    /**
     * 传入页面的基本信息，返回PageInfo封装对象给前端
     * @param pageNum 第几页
     * @param pageSize 每一个元素的数量
     * @return 返回页面封装对象
     */
    @Override
    public PageInfo<Admin> page(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Admin> admins = adminMapper.selectAll();
        return new PageInfo(admins);
    }

    /**
     * 更新admin用户
     * @param admin 传入需要更新的admin用户的信息，根据id修改
     * @return 返回是否更新成功的标志位
     */
    @Override
    public Long update(Admin admin) {
        return adminMapper.updateByAdmin(admin);
    }

    /**
     * 删除指定的admin
     * @param admin 传入需要删除的admin
     */
    @Override
    public void delete(Admin admin) {
        adminMapper.deleteByAdmin(admin);
    }



    /**
     * 添加管理员用户,不能有重复的用户名
     * @param admin 传入的admin用户
     * @return 返回是否插入成功
     */

    @Override
    public JsonResult insert(Admin admin) {
        List<Admin> findAdmin = adminMapper.selectByAdmin(admin);
        if(findAdmin.size() >= 1) {
            return new JsonResult<>(1, "用户名不能重复", null);
        }
        return new JsonResult<>(0, "", adminMapper.addAdmin(admin));
    }

    /**
     * 列出类似username的所有admin用户
     * @param username 传入的是username对应数据库中的username字段
     * @return 返回admin列表
     */
    @Override
    public List<Admin> listLike(String username) {
        return adminMapper.selectByName(username);
    }

    /**
     * 计算admin用户的总数量
     * @return 返回数量
     */
    @Override
    public Long countAdmin() {
        return adminMapper.count();
    }

    /**
     * 返回用户的数量
     * @return 返回数量
     */
    @Override
    public Long countUserWaiting() {
        return userMapper.countUserWaiting();
    }

    /**
     * 返回待审核菜品的数量
     * @return 返回数量
     */
    @Override
    public Long countDishWaiting() {
        return dishMapper.countDishWaiting();
    }

    /**
     * 获得今日的订单数量
     * @param time 传入时间，不一定是传入今天，也可以多日期查询
     * @return 返回数量
     */
    @Override
    public Long getTodayOrders(LocalDateTime time) {
        return orderMapper.countTodayOrders(time);
    }

    /**
     * 获得完成的订单的数量
     * @param time 传入的时间
     * @return 返回数量
     */
    @Override
    public Long getTodayFinishOrders(LocalDateTime time) {
        return orderMapper.countTodayFinishOrders(time);
    }

    /**
     * 获得当天的收益
     * @param time 传入需要查询的时间
     * @return 返回钱
     */
    @Override
    public BigDecimal getTodayOrderMoney(LocalDateTime time) {
        return orderMapper.countTodayOrderMoney(time);
    }

    /**
     * 获得指定日期指定商家的收益
     * @param merchantId 商家id
     * @param time 指定的时间
     * @return 返回钱
     */
    @Override
    public BigDecimal getTodayMerchantMoney(Integer merchantId, LocalDateTime time) {
        return orderMapper.getTodayMerchantMoney(merchantId, time);
    }

    /**
     * 通过id查询admin用户
     * @param id 通过id查询admin用户
     * @return 返回admin用户对象
     */
    @Override
    public Admin getAdminById(Integer id) {
        return adminMapper.selectAllById(id);
    }

    /**
     * 获取所有的Merchant，根据当天的收入进行排名
     * @param time 指定的时间
     * @return 返回列表 MerchantOrderDay为前端显示的model
     */
    @Override
    public List<MerchantOrderDay> getMerchantOrderByTodayMoney(LocalDateTime time) {
        List<MerchantOrderDay> merchantOrderByTodayMoney = orderMapper.getMerchantOrderByTodayMoney(time);
        List<Merchant> allMerchants = merchantMapper.selectAllMerchant();
        HashMap<Integer, Boolean> hasMoney = new HashMap<>();
        for(MerchantOrderDay item : merchantOrderByTodayMoney) {
            hasMoney.put(item.getMerchantId(), true);
            Merchant merchant = merchantMapper.selectById(item.getMerchantId());
            item.setMerchantName(merchant.getShopName());
        }
        for (Merchant allMerchant : allMerchants) {
            if (hasMoney.get(allMerchant.getId()) == null || !hasMoney.get(allMerchant.getId())) {
                MerchantOrderDay emptyItem = new MerchantOrderDay();
                emptyItem.setMerchantName(allMerchant.getShopName());
                emptyItem.setMerchantId(allMerchant.getId());
                emptyItem.setTime(LocalDateTime.now());
                emptyItem.setAmount(BigDecimal.ZERO);
                merchantOrderByTodayMoney.add(emptyItem);
            }
        }
        return merchantOrderByTodayMoney;
    }

    /**
     * 获得指定商家前day天的数据
     * @param merchantId 指定商家的id
     * @param time 指定需要查询的时间
     * @param day 指定查询的天数
     * @return 返回前端显示的model：DateMoneyList（其中有两个列表，一个是时间列表作为横坐标，一个是amount列表作为纵坐标）
     */
    @Override
    public DateMoneyList getMerchantDaysMoney(Integer merchantId, LocalDateTime time, Integer day) {
        if(day <= 0) {
            throw new RuntimeException("提前的时间只能为正数");
        }
        DateMoneyList dateMoneyList = new DateMoneyList();
        List<BigDecimal> moneyList = new ArrayList<>();
        List<LocalDateTime> timeList = new ArrayList<>();
        for(int i = day;i >= 0;i --) { // 遍历这几天，都封装到dateMoneyList对象中
            LocalDateTime localDateTime = time.plusDays((-i));
            BigDecimal bigDecimal = orderMapper.getTodayMerchantMoney(merchantId, localDateTime);
            if(bigDecimal == null) bigDecimal = new BigDecimal(0.0);
            moneyList.add(bigDecimal);
            timeList.add(localDateTime);
        }
        dateMoneyList.setMoneyList(moneyList);
        dateMoneyList.setTimeList(timeList);
        // 返回封装对象，直接到前端处理
        return dateMoneyList;
    }

    /**
     * 通过user增加admin用户表（已弃用）
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public Boolean addAdminFromUser(List<Integer> ids) {
        List<User> users = new ArrayList<>();
        for (Integer id : ids) {
            users.add(userMapper.selectById(id));
        }
        for (User user : users) {
            Admin admin = new Admin();
            admin.setPassword(user.getPassword());
            admin.setUsername(user.getUsername());
            admin.setName(user.getName());
            admin.setPhone(user.getPhone());
            admin.setSex(user.getSex());
            Long aLong = adminMapper.addAdmin(admin);
            if(aLong <= 0) {
                throw new RuntimeException("未能添加管理员");
            }
        }
        return true;
    }

    /**
     * 查询不是管理员的用户（已弃用）
     * @return
     */
    @Override
    public List<User> searchUsersNotAdmin() {
        List<User> users = userMapper.selectAll();
        List<User> resUsers = new ArrayList<>(users);
        for(User user : users) {
            String username = user.getUsername();
            Admin admin = new Admin();
            admin.setUsername(username);
            List<Admin> admins = adminMapper.selectByAdmin(admin);
            if(admins.size() >= 1) {
                resUsers.remove(user);
            }
        }
        return resUsers;
    }
}
